import os
import cv2
import numpy as np
import matplotlib
matplotlib.use('Agg')  # 在导入pyplot前设置
import matplotlib.pyplot as plt
from matplotlib import gridspec
# 设置中文显示
plt.rcParams["font.family"] = ["SimSun"] 
plt.rcParams['axes.unicode_minus'] = False  # 解决负号显示问题
# 1. 灰度变换函数实现
def imadjust(image, low_in=0.0, high_in=1.0, low_out=0.0, high_out=1.0, gamma=1.0):
    """
    实现MATLAB的imadjust函数功能
    """
    img_float = image.astype(np.float32) / 255.0 if image.dtype == np.uint8 else image
    
    if high_in <= low_in:
        raise ValueError("high_in must be greater than low_in")
    
    normalized = (img_float - low_in) / (high_in - low_in)
    
    if gamma != 1.0:
        normalized = np.power(normalized, gamma)
    
    result = normalized * (high_out - low_out) + low_out
    result = np.clip(result, 0.0, 1.0)
    
    return result

def stretchlim(image, p1=0.01, p2=0.99):
    """
    实现MATLAB的stretchlim函数功能
    """
    img_float = image.astype(np.float32) / 255.0 if image.dtype == np.uint8 else image
    
    hist, bins = np.histogram(img_float.flatten(), bins=256, density=True)
    cdf = hist.cumsum()
    cdf = cdf / cdf[-1]
    
    low_in = bins[np.argmin(np.abs(cdf - p1))]
    high_in = bins[np.argmin(np.abs(cdf - p2))]
    
    return [low_in, high_in]
# 创建显示函数
def show_images(images, titles, figsize=(15, 10)):
    """显示多张图像"""
    plt.figure(figsize=figsize)
    gs = gridspec.GridSpec(2, 3, width_ratios=[1, 1, 1], height_ratios=[1, 1])
    
    for i, (img, title) in enumerate(zip(images, titles)):
        ax = plt.subplot(gs[i])
        if img.ndim == 2:  # 灰度图像
            plt.imshow(img, cmap='gray')
        else:  # 彩色图像
            plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
        plt.title(title)
        plt.axis('off')
    
    plt.tight_layout()
    plt.show()
    plt.savefig('results//chapter2-2//images.png')
# 2. 读取图像

breast_image = cv2.imread('images\\dipum_images_ch03\\Fig0303(a)(breast).tif', cv2.IMREAD_GRAYSCALE)
if breast_image is None:
    raise FileNotFoundError

os.makedirs('results//chapter2-2', exist_ok=True)
# 3. 显示原始图像
plt.figure(figsize=(5, 5))
plt.imshow(breast_image, cmap='gray')
plt.title('原始图像 (a)')
plt.axis('off')
plt.show()
plt.savefig('results//chapter2-2//原始图像 (a).png')

# 4. 负片图像
negative_image = 1.0 - imadjust(breast_image, low_in=0, high_in=1)
negative_image_uint8 = (negative_image * 255).astype(np.uint8)

plt.figure(figsize=(5, 5))
plt.imshow(negative_image_uint8, cmap='gray')
plt.title('负片图像 (b)')
plt.axis('off')
plt.show()
plt.savefig('results//chapter2-2//负片图像 (b).png')

# 5. 亮度扩展至[0.5,0.75]
extended_image = imadjust(breast_image, low_in=0.5, high_in=0.75, low_out=0, high_out=1)
extended_image_uint8 = (extended_image * 255).astype(np.uint8)

plt.figure(figsize=(5, 5))
plt.imshow(extended_image_uint8, cmap='gray')
plt.title('亮度扩展至[0.5,0.75] (c)')
plt.axis('off')
plt.show()
plt.savefig('results//chapter2-2//亮度扩展至[0.5,0.75] (c).png')

# 6. Gamma=2增强
gamma_image = imadjust(breast_image, low_in=0, high_in=1, low_out=0, high_out=1, gamma=2)
gamma_image_uint8 = (gamma_image * 255).astype(np.uint8)

plt.figure(figsize=(5, 5))
plt.imshow(gamma_image_uint8, cmap='gray')
plt.title('gamma=2增强 (d)')
plt.axis('off')
plt.show()
plt.savefig('results//chapter2-2//gamma=2增强 (d).png')

# 7. 自动调整（使用stretchlim）
stretch_limits = stretchlim(breast_image)
print("stretchlim计算的范围:", [f"{x:.4f}" for x in stretch_limits])

stretch_image = imadjust(breast_image, low_in=stretch_limits[0], high_in=stretch_limits[1])
stretch_image_out = imadjust(breast_image, low_in=stretch_limits[0], high_in=stretch_limits[1], low_out=0, high_out=1)

stretch_image_uint8 = (stretch_image * 255).astype(np.uint8)
stretch_image_out_uint8 = (stretch_image_out * 255).astype(np.uint8)

images = [stretch_image_uint8, stretch_image_out_uint8]
titles = ['使用stretchlim自动调整 (e)', '使用stretchlim自动调整 (f)']
show_images(images, titles)